home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
130_01
/
view.c
< prev
next >
Wrap
Text File
|
1985-03-09
|
9KB
|
399 lines
/*
VIEW - Disk Block Viewer for CP/M v2
written for BDS "C" v1.44 by
Rick Hollinbeck
Box C
Norwood, CO 81423
v1.0 - 10/19/81
Note:
This program depends on:
1. v2.x CP/M
2. a modified 'bios' function which leaves HL untouched
for the seldsk function (9), but is otherwise compatible
with the standard library version.
3. A CRT with addressable cursor & clear screen capabilities.
4. A 'bdscio.h' with the strings CLEARS (clear screen) and
CURSADR (cursor addressing prefix to row, column) defined.
5. The direct bios disk i/o utilities (diskio.c & diskio.dcl)
*/
#include <a:bdscio.h>
#include <diskio.dcl>
#define ALLXOFF 5 /* Home Row for Allocation Map */
#define ALLYOFF 1 /* Home Column for Allocation Map */
#define MXBITPOS 63 /* Last bit position to display per row */
#define ALLYMAX (ALLYOFF + (MXBITPOS+1)/8 + MXBITPOS - 1)
/* Max column for alloc. map */
#define MXBLOCK 0x4000 /* Maximum Block Size */
#define MAXROW TLENGTH /* CRT Maximum row */
#define MAXCOL TWIDTH /* CRT Maximum column */
/* CP/M 2.x Disk Parameter Tables */
struct dpb { /* Disk Parameter Block */
unsigned spt; /* Sectors/track */
char bsh; /* block shift (3 = 1k, 4 = 2k, 5 = 4k, etc.) */
char blm; /* a bit mask 'bsh' bits wide */
char exm; /* extent mask (depends on dsm, 0 for 1k allocation) */
unsigned dsm; /* maximum block number for drive */
unsigned drm; /* maximum directory entry index */
char al[2]; /* Directory Allocation Bitmap */
unsigned cks; /* size of checksum vector */
unsigned off; /* Number of reserved tracks */
} *dpbp; /* from dphp->hdpbp */
struct dph { /* Disk Parameter Header */
char *xltp; /* pointer to sector translation table */
int dscr[3]; /* BDOS scratch */
char *dirbp; /* Pointer to directory buffer */
struct dpb *hdpbp; /* Disk Parameter Block pointer */
char *csvp; /* Pointer to checksum vector */
char *alvp; /* Pointer to Allocation Bitmap */
} *dphp; /* returned by seldsk */
unsigned bls; /* block size (bytes) */
char curx, cury, bitpos, maxxpos, lstmxbit;
char scurx, scury;
char svcurx, svcury;
char i, j, *dbufp, *bufp1, lineno;
char *xltbp;
unsigned usedblks, block, ii, jj, maxtrk, maxsec;
struct dskadr dadr;
char c, cdisk, abort;
char ans[132];
char dbuf[MXBLOCK]; /* Block Buffer */
main()
{
strt:
clearscrn();
cursor(MAXROW/2, 0);
printf("Disk Block Viewer");
printf(" v1.0\n");
getdsk:
printf("Enter Drive (A:, B:, etc.): ");
gets(ans);
bdos(14, c = (cdisk = toupper(ans[0])) - 'A'); /* Log in Drive */
if (!(dphp = bios(SELDSK, c))) {
printf("\n??? Select Error on %c:\n", cdisk);
goto getdsk;
}
maxtrk = maxsec = (-1); /* Disable diskio parameter checks */
bitpos = 0;
scurx = ALLXOFF;
scury = ALLYOFF;
cloop:
abort = FALSE;
diskinfo(); /* Print Disk Characteristics */
printbm(); /* Print allocation map */
/* Block select loop */
cursor(curx + 2, 3);
printf("F - Fwd / B - Back / P - Up / N - Down / X - Examine");
printf(" / S - Select Disk");
printst(); /* Print sector translation table */
cursor(scurx, scury);
c = ' ';
while (c != ('C'-0x40)) { /* ^C terminates */
block = (curx - ALLXOFF) * (MXBITPOS + 1) + bitpos;
cursave();
cursor(MAXROW - 1, MAXCOL - 30);
printf("Block %u (dec) %x (hex) ", block, block);
curback();
switch (c = toupper(getch())) {
case ('F'-0x40): /* ^F */
case 'F':
if (block < dpbp->dsm)
if (bitpos < MXBITPOS) {
if ((bitpos & 7) == 7) ++cury;
cursor(curx, ++cury);
++bitpos;
}
else { /* wrap to next line */
cursor(++curx, ALLYOFF);
bitpos = 0;
}
break;
case ('B'-0x40): /* ^B */
case 'B':
if (bitpos) {
if (!(bitpos & 7)) --cury;
cursor(curx, --cury);
--bitpos;
}
else { /* back up to previous line */
if (curx > ALLXOFF) {
cursor(--curx, ALLYMAX);
bitpos = MXBITPOS;
}}
break;
case ('N'-0x40): /* ^N */
case 'N':
if (curx < maxxpos) {
cursor(++curx, cury);
}
break;
case ('P'-0x40): /* ^P */
case 'P':
if (curx > ALLXOFF) {
cursor(--curx, cury);
}
break;
case ('X'-0x40): /* ^X */
case 'X':
/* Get the block & Display it */
scurx = curx;
scury = cury;
cursor(MAXROW - 3, 0);
readblk(block);
for (dbufp = dbuf; dbufp < &dbuf[bls]; ++dbufp) {
if ((c = *dbufp) == CPMEOF) break;
if (c == '\r') continue;
if (c == '\n') continue;
if (c == '\t') continue;
if (!printable(c)) {
cursor(curx + 2, 0);
printf("Looks binary, interested? ");
if (!yes()) goto cloop;
dmphex();
goto cxdone;
}
}
cursor(curx + 2, 0);
printf("Looks like ASCII, Do you want hex display anyway? ");
if (yes()) dmphex();
else dmpascii();
cxdone:
if (!abort) {
newline();
pause();
}
goto cloop;
case ('S'-0x40):
case 'S':
goto strt;
}
}
cursor (MAXROW - 2, 0);
exit();
}
diskinfo()
{
/* Print Disk Info */
dpbp = dphp->hdpbp;
printf("%sDrive %c Characteristics:\n", CLEARS, cdisk);
printf("Sectors per Track: %u ", dpbp->spt);
/* Calc block size */
printf("Block Size: %u ",
bls = SECSIZ << dpbp->bsh);
printf("Max Block: %u ", dpbp->dsm);
printf("Disk Size: %uk\n",
dpbp->dsm << (dpbp->bsh - 3));
printf("Reserved Tracks: %u", dpbp->off);
}
readblk(blk)
unsigned blk;
{
/* Determine the block's disk address */
dadr.track = (jj = (ii = bls/SECSIZ) * blk) / dpbp->spt + dpbp->off;
jj = jj % dpbp->spt;
dadr.sector = physec(jj);
clearscrn();
printf("Reading Track - Sector\n");
dbufp = dbuf;
while (ii--) {
cursor(++curx,10); printf("%u", dadr.track);
cursor(curx, 18); printf("%u", dadr.sector);
diskio(READ, &dadr, dbufp, 1, maxtrk, maxsec);
dbufp += SECSIZ;
if (++jj == dpbp->spt) {
jj = 0;
++dadr.track;
}
dadr.sector = physec(jj);
}
}
unsigned physec(logsec)
unsigned logsec;
{
return dphp->xltp ? *(dphp->xltp + logsec) : (logsec + 1);
}
printbm()
{
char abyt, bmsk, bit, *almapp;
unsigned bcnt;
cursor(ALLXOFF - 2, (MAXCOL/2 - 12));
printf("Allocation Bit Map\n");
cursor(maxxpos = (ALLXOFF - 1), ALLYOFF);
printf("0 7 8 15 16 23 24 31 32 39 40 47");
printf(" 48 55 56 63");
almapp = dphp->alvp; /* point to allocation map */
usedblks = 0;
for (bcnt = 0; bcnt <= dpbp->dsm; ++bcnt) {
if (bcnt & 7) { /* shift to next bit */
bit = ((abyt & (bmsk >>= 1)) != 0);
}
else { /* get next byte from vector */
bit = (((abyt = *almapp++) & (bmsk = 0x80)) != 0);
if (!(bcnt & 0x3f)) {
++maxxpos;
lstmxbit = 0;
cursor(++curx, ALLYOFF - 1);
}
printf(" ");
}
++lstmxbit;
printf("%u",bit);
usedblks += bit;
}
--lstmxbit;
/* Print total allocated storage */
cursave();
cursor(ALLXOFF - 3, MAXCOL - 22);
printf("Blks Used: %u", usedblks);
curback();
}
printst()
{
cursor(curx + 2, (MAXCOL/2 - 12));
printf("Sector Translation");
cursor(++curx, 0);
xltbp = dphp->xltp;
for (i = j = 0; i < dpbp->spt; ++i) {
if (j++ == (MAXCOL/8)) {
cursor(++curx, 0);
j = 1;
}
printf("%u:%u ", i+1, *xltbp++);
cursor(curx, cury + 8);
}
}
dmphex()
{
clearscrn();
ii = 0;
for (dbufp = dbuf; dbufp < &dbuf[bls];) {
newline();
if (abort) return;
printf("%c%c%c0: ", hexd(ii>>8),
hexd(ii>>4), hexd(ii));
++ii;
bufp1 = dbufp;
for (j=0; j<16; ++j)
{
printf("%c%c ", hexd(*dbufp>>4),
hexd(*dbufp));
++dbufp;
}
printf(" |");
dbufp = bufp1;
for (j=0; j<16; ++j) {
putchar( printable(*dbufp) ? *dbufp : '_');
++dbufp;
}
printf("|");
}
}
dmpascii()
{
clearscrn();
for (dbufp = dbuf; dbufp < &dbuf[bls]; ++dbufp) {
if ((c = *dbufp) == CPMEOF) break;
if (c == '\n') newline();
else putchar(c);
if (abort) return;
}
}
char hexd(dbyte)
char dbyte;
{
return
( ((dbyte = dbyte & 0x0f) > 9